package com.bwda.dsrs.systemservice.controller;


import com.bwda.dsrs.base.centerbase.response.CentreCutPageResponse;
import com.bwda.dsrs.base.centerbase.response.CentreListResponse;
import com.bwda.dsrs.base.centerbase.response.ResponseEntity;
import com.bwda.dsrs.base.util.CopyUtil;
import com.bwda.dsrs.systemservice.annotations.NeedRole;
import com.bwda.dsrs.systemservice.aspect.LogTypeEnum;
import com.bwda.dsrs.systemservice.aspect.Loggable;
import com.bwda.dsrs.systemservice.domain.Constants;
import com.bwda.dsrs.systemservice.domain.condition.menu.MenuCondition;
import com.bwda.dsrs.systemservice.domain.condition.menuright.MenuRightCondition;
import com.bwda.dsrs.systemservice.domain.condition.role.RoleCondition;
import com.bwda.dsrs.systemservice.domain.condition.user.UserCondition;
import com.bwda.dsrs.systemservice.domain.condition.userrole.UserRoleCondition;
import com.bwda.dsrs.systemservice.domain.exception.SystemServiceException;
import com.bwda.dsrs.systemservice.domain.form.menu.MenuTree;
import com.bwda.dsrs.systemservice.domain.form.menu.MenuTreeForm;
import com.bwda.dsrs.systemservice.domain.form.menuright.MenuRightCreateForm;
import com.bwda.dsrs.systemservice.domain.form.menuright.MenuRightQueryForm;
import com.bwda.dsrs.systemservice.domain.form.role.RoleCreateForm;
import com.bwda.dsrs.systemservice.domain.form.role.RoleQueryForm;
import com.bwda.dsrs.systemservice.domain.form.role.RoleUpdateForm;
import com.bwda.dsrs.systemservice.domain.form.role.UserAndRoleForm;
import com.bwda.dsrs.systemservice.domain.form.user.UserQueryForm;
import com.bwda.dsrs.systemservice.domain.form.userrole.UserRoleCreateForm;
import com.bwda.dsrs.systemservice.domain.po.menu.MenuPo;
import com.bwda.dsrs.systemservice.domain.po.menuright.MenuRightPo;
import com.bwda.dsrs.systemservice.domain.po.org.OrgPo;
import com.bwda.dsrs.systemservice.domain.po.role.RolePo;
import com.bwda.dsrs.systemservice.domain.po.role.UserByRolePo;
import com.bwda.dsrs.systemservice.domain.po.user.UserPo;
import com.bwda.dsrs.systemservice.domain.po.userrole.UserRolePo;
import com.bwda.dsrs.systemservice.domain.vo.menu.MenuVo;
import com.bwda.dsrs.systemservice.domain.vo.menuright.MenuRightVo;
import com.bwda.dsrs.systemservice.domain.vo.role.RoleVo;
import com.bwda.dsrs.systemservice.domain.vo.userrole.UserRoleVo;
import com.bwda.dsrs.systemservice.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;

/**
 * 系统管理--角色管理--控制层
 *
 * @author zhangyinmei
 * @date 2019年5月6日
 */
@RestController
@RequestMapping("/s/role")
@Api(value = "/s/role", tags = "角色表")
public class RoleController extends BaseController {

	private static Logger logger = LoggerFactory.getLogger(RoleController.class);

	@Autowired
	private RoleService roleService;

	@Autowired
	private UserRoleService userRoleService;

	@Autowired
	private UserService userService;

	@Autowired
	private MenuService menuService;

	@Autowired
	private MenuRightService menuRightService;

	@Autowired
	private OrgService orgService;

	/**
	 * 根据角色ID查询授权菜单
	 *
	 * @param roleId
	 * @return
	 * @throws SystemServiceException
	 */
	@Loggable(descp = "根据角色ID查询授权菜单",type = LogTypeEnum.QUERY,include = "")
	@ApiOperation(value = "根据角色ID查询授权菜单", notes = "根据角色ID查询授权菜单", httpMethod = "POST")
	@PostMapping(value = "/queryMenuListByRoleId")
	public ResponseEntity<CentreListResponse<MenuVo>> queryMenuListByRoleId(@RequestBody Integer roleId) throws SystemServiceException {
		logger.info("根据角色ID查询授权菜单");
		MenuRightCondition menuRightCondition = new MenuRightCondition();
		menuRightCondition.setRoleId(roleId);
		List<MenuRightPo> poList = menuRightService.queryList(menuRightCondition);

		if(poList != null && !poList.isEmpty()){
			List<Integer> menuIdList = new ArrayList<Integer>();
			for(MenuRightPo menuRightPo : poList){
				menuIdList.add(menuRightPo.getMenuId());
			}
			MenuCondition menuCondition = new MenuCondition();
			menuCondition.setIdList(menuIdList);
			List<MenuPo> menuPoList = menuService.queryList(menuCondition);
			List<MenuVo> menuVoList = CopyUtil.transfer(menuPoList, MenuVo.class);
			return getSuccessResult(getListResponse(menuVoList));
		}else{
			return getFailResult("角色未关联菜单。");
		}
	}

	/**
	 * 查询用户关联的角色列表
	 *
	 * @param userCode 用户编码
	 * @return
	 * @throws SystemServiceException
	 */
	@Loggable(descp = "查询用户关联的角色列表",type = LogTypeEnum.QUERY,include = "")
	@ApiOperation(value = "查询用户关联的角色列表", notes = "查询用户关联的角色列表", httpMethod = "POST")
	@RequestMapping(value = "/queryUserRoleList", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<CentreListResponse<RoleVo>> queryUserRoleList(@RequestBody String userCode) throws SystemServiceException {
		logger.info("查询用户关联的角色列表");

		List<RolePo> rolePoList = roleService.queryUserRoleList(userCode);
		if(rolePoList != null && !rolePoList.isEmpty()){
			List<RoleVo> roleVoList = CopyUtil.transfer(rolePoList, RoleVo.class);
			return getSuccessResult(getListResponse(roleVoList));
		}else{
			return getFailResult(201,"用户未关联角色。");
		}
	}


	/**
	 * 新增菜单权限表
	 *
	 * @param form
	 * @return
	 * @throws SystemServiceException
	 */
	@ApiOperation(value = "新增菜单权限表", notes = "新增菜单权限表", httpMethod = "POST")
	@Loggable(descp = "查询用户关联的角色列表",type = LogTypeEnum.QUERY,include = "")
	@RequestMapping(value = "/addMenuRight", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<MenuRightVo> addMenuRight(@ModelAttribute @Valid MenuRightCreateForm form) throws SystemServiceException {
		logger.info("新增菜单权限表");
		if(form.getRoleId() == null){
			return getFailResult("请传入角色ID");
		}
		//先删除
		menuRightService.delete(form.getRoleId());
		//再新增
		List<Integer> menuIdList = form.getMenuIdList();
		MenuRightPo menuRightPo = new MenuRightPo();
		menuRightPo.setRoleId(form.getRoleId());
		if(menuIdList != null && !menuIdList.isEmpty()){
			for(Integer menuId : menuIdList){
				menuRightPo.setMenuId(menuId);
				menuRightService.insert(menuRightPo);
			}
		}
		return getSuccessResult();
	}


	/**
	 * 查询菜单树
	 *
	 * @return
	 * @throws SystemServiceException
	 */
	@Loggable(descp = "查询菜单树",type = LogTypeEnum.QUERY,include = "")
	@ApiOperation(value = "查询菜单树", notes = "查询菜单树", httpMethod = "GET")
	@RequestMapping(value = "/queryMenuTree", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<List<MenuTreeForm>> queryAllMenuTree() throws SystemServiceException {
		logger.info("查询菜单树");
		List<MenuTreeForm> poList = menuService.queryTreeList(new MenuCondition());
		//设置icon为null
		if(poList != null){
			for(MenuTreeForm menuTreeForm : poList){
				menuTreeForm.setIcon(null);
			}
		}
		List<MenuTreeForm> treeList = menuService.queryTree(poList);
		return getSuccessResult(treeList);
	}

	/**
	 * 查询菜单树
	 *
	 * @return
	 * @throws SystemServiceException
	 */
	@Loggable(descp = "查询菜单树",type = LogTypeEnum.QUERY,include = "")
	@ApiOperation(value = "查询菜单树", notes = "查询菜单树", httpMethod = "GET")
	@RequestMapping(value = "/queryUserMenuTree", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<List<MenuTree>> queryUserMenuTree(HttpServletRequest request) throws SystemServiceException {
		logger.info("查询菜单树");
		logger.info("获取当前用户code");
		//获取当前用户code
		String userCode = getUserCode();
		//根据userCode获取角色
		List<RolePo> rolePoList = roleService.queryUserRoleList(userCode);
		if(rolePoList == null || rolePoList.isEmpty()){
			return getFailResult("当前用户还未绑定角色，请先绑定角色。");
		}
		List<Integer> roleIdList = new ArrayList<>();
		for(RolePo rolePo : rolePoList){
			roleIdList.add(rolePo.getId());
		}
		MenuRightCondition menuRightCondition = new MenuRightCondition();
		menuRightCondition.setPageSize(Integer.MAX_VALUE);
		menuRightCondition.setRoleIdList(roleIdList);
		List<MenuRightPo> menuRightPoList = menuRightService.queryList(menuRightCondition);
		if(menuRightPoList == null || menuRightPoList.isEmpty()){
			return getFailResult("当前用户还未绑定菜单，请先给用户角色绑定菜单。");
		}
		List<Integer> menuIdList = new ArrayList<>();
		for(MenuRightPo menuRightPo : menuRightPoList){
			menuIdList.add(menuRightPo.getMenuId());
		}
		MenuCondition menuCondition = new MenuCondition();
		menuCondition.setIdList(menuIdList);
		//增加未禁用的条件
		menuCondition.setIsShow(Constants.TYPE_ID);
		List<MenuTreeForm> poList = menuService.queryTreeList(menuCondition);
		List<MenuTree> treeList = menuService.queryMenuTree(poList);
		return getSuccessResult(treeList);
	}

	/**
	 * 按级查询菜单树
	 *
	 * @return
	 * @throws SystemServiceException
	 */
	@Loggable(descp = "按级查询菜单树",type = LogTypeEnum.QUERY,include = "")
	@ApiOperation(value = "按级查询菜单树", notes = "按级查询菜单树", httpMethod = "GET")
	@RequestMapping(value = "/queryUserMenuSingleTree", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<List<MenuTree>> queryUserMenuSingleTree(MenuRightQueryForm form, HttpServletRequest request) throws SystemServiceException {
		logger.info("查询菜单树");
		logger.info("获取当前用户code");
		//获取当前用户code
		String userCode = getUserCode();
		//根据userCode获取角色
		List<RolePo> rolePoList = roleService.queryUserRoleList(userCode);
		if(rolePoList == null || rolePoList.isEmpty()){
			return getFailResult("当前用户还未绑定角色，请先绑定角色。");
		}
		List<Integer> roleIdList = new ArrayList<>();
		for(RolePo rolePo : rolePoList){
			roleIdList.add(rolePo.getId());
		}
		MenuRightCondition menuRightCondition = new MenuRightCondition();
		menuRightCondition.setPageSize(Integer.MAX_VALUE);
		menuRightCondition.setRoleIdList(roleIdList);
		List<MenuRightPo> menuRightPoList = menuRightService.queryList(menuRightCondition);
		if(menuRightPoList == null || menuRightPoList.isEmpty()){
			return getFailResult("当前用户还未绑定菜单，请先给用户角色绑定菜单。");
		}
		List<Integer> menuIdList = new ArrayList<>();
		for(MenuRightPo menuRightPo : menuRightPoList){
			menuIdList.add(menuRightPo.getMenuId());
		}
		MenuCondition menuCondition = new MenuCondition();
		if(form.getId()!=null){
			menuCondition.setParentMenuId(form.getId());
		}else{
			menuCondition.setParentMenuId(Constants.ZERO_INT);
		}
		menuCondition.setIdList(menuIdList);
		menuCondition.setIsShow(1);
		List<MenuTreeForm> poList = menuService.queryTreeList(menuCondition);
		List<MenuTree> treeList = menuService.queryMenuTreeSingle(poList);
		return getSuccessResult(treeList);
	}


	/**
	 * 查询菜单树(菜单授权排除三元菜单)
	 *
	 * @return
	 * @throws SystemServiceException
	 */
	@Loggable(descp = "查询菜单树",type = LogTypeEnum.QUERY,include = "")
	@ApiOperation(value = "查询菜单树", notes = "查询菜单树", httpMethod = "GET")
	@RequestMapping(value = "/queryAuthMenuTree", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<List<MenuTree>> queryAuthMenuTree(HttpServletRequest request) throws SystemServiceException {
		logger.info("查询授权菜单树");
		MenuCondition menuCondition = new MenuCondition();
		menuCondition.setPageSize(Integer.MAX_VALUE);
		menuCondition.setIsSysMenu(Constants.ZERO_INT);
		List<MenuTreeForm> poList = menuService.queryTreeList(menuCondition);
		List<MenuTree> treeList = menuService.queryMenuTree(poList);
		return getSuccessResult(treeList);
	}

	/**
	 * 查询角色表列表
	 *
	 * @param form
	 * @return
	 * @throws SystemServiceException
	 */
	@Loggable(descp = "查询角色表列表",type = LogTypeEnum.QUERY,include = "")
	@ApiOperation(value = "查询角色表列表(带分页)",notes = "查询角色表列表(带分页)",httpMethod = "GET")
	@RequestMapping(value = "/queryPageList", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<CentreCutPageResponse<RoleVo>> queryPageList(@ModelAttribute@Valid RoleQueryForm form) throws SystemServiceException {
		logger.info("查询角色表列表");
		RoleCondition condition = this.getConditionByQueryForm(form);
		//设置未删除条件
		condition.setDelFlag(Constants.NOT_DELETED);
		//设置展示
		condition.setShowFlag(Constants.NOT_DELETED);
		List<RoleVo> voList = new ArrayList<>();
		int count = roleService.queryCount(condition);
		if (count > Constants.NOT_DELETED) {
			List<RolePo> poList = roleService.queryList(condition);
			voList = CopyUtil.transfer(poList, RoleVo.class);
			//添加角色已经绑定的菜单ID数组
			MenuRightCondition menuRightCondition = new MenuRightCondition();
			List<MenuRightPo> menuRightPoList;
			List<String> menuIdList;
			for(RoleVo roleVo : voList){
				menuRightCondition.setRoleId(roleVo.getId());
				menuRightPoList = menuRightService.queryList(menuRightCondition);
				if(menuRightPoList != null && !menuRightPoList.isEmpty()){
					menuIdList = new ArrayList<String>();
					for(MenuRightPo menuRightPo : menuRightPoList){
						menuIdList.add(menuRightPo.getMenuId().toString());
					}
					roleVo.setMenuIdList(menuIdList);
				}
			}
		}
		return getSuccessResult(getPageResponse(form, count, voList));
	}

	/**
	 * 新增角色
	 *
	 * @param form
	 * @return
	 * @throws SystemServiceException
	 */
	@NeedRole("sysadminrole")
	@Loggable(descp = "新增角色",type = LogTypeEnum.CREATE,include = "")
	@ApiOperation(value = "新增角色表",notes = "新增角色表",httpMethod = "POST")
	@RequestMapping(value = "/add", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<RoleVo> add(@ModelAttribute@Valid RoleCreateForm form) throws SystemServiceException {
		logger.info("新增角色");
		if(StringUtils.isNotBlank(form.getRoleName())){
			RoleCondition condition = new RoleCondition();
			condition.setRoleName(form.getRoleName());
			int count = roleService.queryCount(condition);
			if(count>Constants.ZERO_INT){
				return getFailResult("相同角色名称不可重复设置。");
			}
		}
		RolePo po = CopyUtil.transfer(form, RolePo.class);
		//设置创建时间
		po.setCreateTime(new Date());
		//设置是否删除为未删除
		po.setDelFlag(Constants.NOT_DELETED);
		//设置状态为启用
		po.setStatus(Constants.StateType.ENABLE);
		//设置为自定义
		po.setIsDefault(Constants.IS_NOT_DEFAULT);
		//设置数据范围为所以数据，这边需要确认一下！
		po.setDataScope(Constants.DataScope.ALL_DATA);
		roleService.insert(po);
		RoleVo vo = CopyUtil.transfer(po, RoleVo.class);
		return getSuccessResult(vo);
	}

	/**
	 * 修改角色
	 *
	 * @param form
	 * @return
	 * @throws SystemServiceException
	 */
	@NeedRole("sysadminrole")
	@Loggable(descp = "修改角色",type = LogTypeEnum.UPDATE,include = "")
	@ApiOperation(value = "修改角色表",notes = "修改角色表",httpMethod = "POST")
	@RequestMapping(value = "/update", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity update(@ModelAttribute@Valid RoleUpdateForm form) throws SystemServiceException {
		logger.info("修改角色");
		if(StringUtils.isNotBlank(form.getRoleName())){
			RoleCondition rcondition = new RoleCondition();
			rcondition.setRoleName(form.getRoleName());
			List<RolePo> list = roleService.queryList(rcondition);
			if(list!=null&&list.size()>Constants.ZERO_INT){
				RolePo rolePo = list.get(Constants.ZERO_INT);
				if(form.getRoleName().equals(rolePo.getRoleName())&&!form.getId().equals(rolePo.getId())){
					return getFailResult("相同角色名称不可重复设置。");
				}
			}
		}
		RolePo po = CopyUtil.transfer(form, RolePo.class);
		roleService.update(po);
		return getSuccessResult();
	}

	/**
	 * 删除角色
	 *
	 * @param id
	 * @return
	 * @throws SystemServiceException
	 */
	@NeedRole("sysadminrole")
	@Loggable(descp = "删除角色",type = LogTypeEnum.DELETE,include = "")
	@ApiOperation(value = "删除角色表",notes = "删除角色表",httpMethod = "POST")
	@RequestMapping(value = "/delete", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity delete(@ApiParam(value = "ID主键", required = true)@RequestParam Integer id) throws SystemServiceException {
		UserRoleCondition condition = new UserRoleCondition();
		condition.setRoleId(id);
		int count = userRoleService.queryCount(condition);
		if(count>0){
			return getFailResult("该角色下绑定用户，不可删除");
		}
		logger.info("删除角色");
		//逻辑删除，故更新为已删除即可。
		RolePo po = new RolePo();
		//设置ID
		po.setId(id);
		//设置是否删除状态为已删除。
		po.setDelFlag(Constants.DELETED);
		roleService.update(po);
		return getSuccessResult();
	}


	/**
	 * 角色关联用户
	 *
	 * @param form
	 * @return
	 * @throws SystemServiceException
	 */
	@NeedRole("sysadminrole")
	@Loggable(descp = "角色关联用户",type = LogTypeEnum.SETTING,include = "")
	@ApiOperation(value = "角色关联用户", notes = "角色关联用户", httpMethod = "POST")
	@RequestMapping(value = "/addUserRole", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<UserRoleVo> addUserRole(@ModelAttribute @Valid UserRoleCreateForm form) throws SystemServiceException {
		logger.info("角色关联用户");
		if(form.getRoleId() == null){
			return getFailResult("请传入角色ID");
		}
		UserRolePo po = CopyUtil.transfer(form, UserRolePo.class);
		if (Constants.FIVE_INT.equals(form.getRoleId())){
			UserRoleCondition condition = new UserRoleCondition();
			condition.setRoleId(form.getRoleId());
			List<UserRolePo> list = userRoleService.queryList(condition);
			List list1=	form.getUserCodeList();
			for (int i = 0;i<list.size();i++){
				if (!list1.contains(list.get(i).getUserCode())){
					List<OrgPo>	list2= orgService.queryOrgByUserCode(list.get(i).getUserCode());
					for (int j = 0;j<list2.size();j++){
						orgService.updateOrgAdmin(Constants.GROUP_ADMIN_CODE,list2.get(j).getId());
					}

				}
			}
		}
		//先删除后增加（物理删除）
		userRoleService.delete(po.getRoleId());
		List<String> userCodeList = po.getUserCodeList();
		for(String userCode : userCodeList){
			//设置用户编码
			po.setUserCode(userCode);
			userRoleService.insert(po);
		}
		UserRoleVo vo = CopyUtil.transfer(po, UserRoleVo.class);
		return getSuccessResult(vo);
	}


	@Loggable(descp = "查询用户表列表",type = LogTypeEnum.QUERY,include = "")
	@ApiOperation(value = "查询用户表列表(带分页)", notes = "查询用户表列表(带分页)", httpMethod = "GET")
	@RequestMapping(value = "/queryUserList", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<CentreCutPageResponse<UserByRolePo>> queryPageList(@ModelAttribute @Valid UserAndRoleForm form) throws SystemServiceException {
		UserCondition userCondition = new UserCondition();
		userCondition.setOrgId(form.getOrgId());
		userCondition.setPageSize(form.getPageSize());
		userCondition.setPageNum(form.getPageNum());
		userCondition.setUserCode(form.getUserCode());
		userCondition.setUserName(form.getUserName());

		List<UserPo> userPoList = new ArrayList<UserPo>();
		int count = userService.queryCount(userCondition);
		if (count > Constants.NOT_DELETED) {
			userPoList = userService.queryList(userCondition);
		}
		List<UserByRolePo> userByRolePoList = new ArrayList<UserByRolePo>();
		for(UserPo userPo : userPoList){
			userByRolePoList.add(this.getUserConditionByUserPo(userPo));
		}

		return getSuccessResult(getPageResponse(form, count, userByRolePoList));
	}

	@ApiOperation(value = "查询角色等级列表（不分页）", notes = "查询用户等级列表", httpMethod = "GET")
	@Loggable(descp = "查询角色等级列表（不分页）",type = LogTypeEnum.QUERY,include = "")
	@RequestMapping(value = "/queryListForRoleId", method = {RequestMethod.GET, RequestMethod.POST})
	public ResponseEntity<CentreListResponse<UserPo>> queryListForRoleId(@ApiParam(value = "roleId", required = true)@RequestParam Integer roleId) throws SystemServiceException {
		List<UserPo> poList = userService.selectListForRoleId(roleId);
		return getSuccessResult(getListResponse(poList));
	}



	/**
	 * RoleQueryForm转换为RoleCondition
	 *
	 * @param form
	 * @return
	 */
	private RoleCondition getConditionByQueryForm(RoleQueryForm form) {
		RoleCondition condition = CopyUtil.transfer(form, RoleCondition.class);
		return condition;
	}
	private UserCondition getUserConditionByQueryForm(UserQueryForm form) {
		UserCondition condition = CopyUtil.transfer(form, UserCondition.class);
		return condition;
	}
	private UserByRolePo getUserConditionByUserPo(UserPo userPo) {
		UserByRolePo userByRolePo = CopyUtil.transfer(userPo, UserByRolePo.class);
		return userByRolePo;
	}
}